package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageBean;
import com.zzyl.dto.UserDto;
import com.zzyl.entity.Role;
import com.zzyl.entity.User;
import com.zzyl.entity.UserRole;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.UserMapper;
import com.zzyl.mapper.UserRoleMapper;
import com.zzyl.service.UserService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.utils.ThreadLocalUtil;
import com.zzyl.vo.UserVo;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * 用户表服务实现类
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    final UserMapper userMapper;
    final UserRoleMapper userRoleMapper;
    final RoleMapper roleMapper;

    /**
     * 分页条件查询用户信息
     *
     * @param pageNum
     * @param pageSize
     * @param userDto
     * @return
     */
    @Override
    @Cacheable(cacheNames = "user",key = "#pageNum + #pageSize + #userDto.hashCode()")     //查询添加缓存，优化下次查询速度
    public PageBean<UserVo> pageQueryUser(Integer pageNum, Integer pageSize, UserDto userDto) {
//        1.设置分页参数
        PageHelper.startPage(pageNum,pageSize);

//        2.提取部门有效位
        String deptNo = NoProcessing.processString(userDto.getDeptNo());
        userDto.setDeptNo(deptNo);

//        // 3. 调Mapper分页查询（一次性解法，所有压力给到Mapper层，sql语句会更复杂，返回值是ResultMap，还要写映射规则）
//        Page<UserVo> page = userMapper.getPage(userDto);


//        3.用户和岗位、部门一对多，一个Mapper搞定；与角色属于多对多，需要额外设置
        Page<User> userPage = userMapper.selectPage(userDto);
        PageBean<UserVo> pageBean = PageBean.of(userPage, UserVo.class);

        // 4. 装配角色
        pageBean.getRecords().forEach(userVo ->{
//            1.根据用户ID查询角色
            List<Role> roleList = roleMapper.findRoleListByUserId(userVo.getId());

//            2.拿到角色集合中每一个ID和名称
            List<String> roleIds = CollUtil.getFieldValues(roleList, "id", String.class);
            List<String> roleNames = CollUtil.getFieldValues(roleList, "roleName", String.class);

//            3.设置到每个用户上
            userVo.setRoleVoIds(Set.copyOf(roleIds));
            userVo.setRoleLabels(Set.copyOf(roleNames));
        });

        return pageBean;
    }

    /**
     * 查询用户列表
     *
     * @param userDto
     * @return
     */
    @Override
    @Cacheable(cacheNames = "user",key = "#userDto.hashCode()")
    public List<UserVo> findUserList(UserDto userDto) {

        return null;
    }

    /**
     * 用户添加
     *
     * @param userDto
     */
    @Override
    @Transactional
    @CacheEvict(cacheNames = "user",allEntries = true)      //增删改操作会修改数据库的值，但查询仍是缓存的值，此时就需要清缓存
    public void createUser(UserDto userDto) {
//        1.新增用户
        User user = BeanUtil.toBean(userDto, User.class);
        user.setDataState("0");    //状态 0：正常
        user.setPassword(DigestUtil.bcrypt("888itcast.CN764%..."));
        userMapper.insert(user);    //状态 、 是否动态添加


//        2.新增中间表
        Set<String> roleVoIds = userDto.getRoleVoIds();
        UserRole userRole = UserRole.builder()
                .userId(user.getId())
                .dataState("0")
                .build();
        for (String roleVoId : roleVoIds) {
            userRole.setRoleId(Long.parseLong(roleVoId));
            userRoleMapper.insert(userRole);
        }
    }

    /**
     * 用户修改
     *
     * @param userDto
     */
    @Override
    @CacheEvict(cacheNames = "user",allEntries = true)      //增删改操作会修改数据库的值，但查询仍是缓存的值，此时就需要清缓存
    public void updateUser(UserDto userDto) {
        User user = BeanUtil.toBean(userDto, User.class);
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 启用禁用用户
     *
     * @param id
     * @param status
     */
    @Override
    @CacheEvict(cacheNames = "user",allEntries = true)      //增删改操作会修改数据库的值，但查询仍是缓存的值，此时就需要清缓存
    public void enableOrDisableUser(Long id, String status) {
        User user = User.builder()
                .id(id)
                .dataState(status)
                .build();
        userMapper.updateByPrimaryKeySelective(user);

    }

    /**
     * 删除用户
     *
     * @param userIds
     */
    @Override
    @CacheEvict(cacheNames = "user",allEntries = true)      //增删改操作会修改数据库的值，但查询仍是缓存的值，此时就需要清缓存
    public void deleteUser(String userIds) {
//        1.删除用户表
        Long userId = Long.valueOf(userIds);
        userMapper.deleteByPrimaryKey(userId);

//        2.删除中间表
        userRoleMapper.deleteUserRoleByUserId(userId);
    }

    /**
     * 重置用户密码
     *
     * @param userId
     */
    @Override
    @CacheEvict(cacheNames = "user",allEntries = true)      //增删改操作会修改数据库的值，但查询仍是缓存的值，此时就需要清缓存
    public void resetPassword(String userId) {
        User user = userMapper.selectByPrimaryKey(Long.valueOf(userId));
        user.setPassword(DigestUtil.bcrypt("888itcast.CN764%..."));
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 获取当前登录用户信息(数据回显)
     *
     * @return
     */
    @Override
    public UserVo getUserInfo() {
        Long userId = ThreadLocalUtil.get();
        User user = userMapper.selectUserByUserId(userId);
        return BeanUtil.toBean(user,UserVo.class);
    }


}
